package com.song.JavaThread_day07.ch7_2;

import java.util.Date;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class MyExecutor extends ThreadPoolExecutor {
	
	
	private  ConcurrentHashMap<String, Date> startTimes;

	private ConcurrentHashMap<String, Date> map = new ConcurrentHashMap<>();

	
	public MyExecutor(int corePoolSize, int maximumPoolSize,
			long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
		
		startTimes = new ConcurrentHashMap<String, Date>();
	}


	@Override
	public void shutdown() {
		
		System.out.printf(" MyExecutor :going to shudown .\n");
		System.out.printf(" MyExecutor : Executed tasks: %d \n",getCompletedTaskCount());
		System.out.printf(" MyExecutor : Runing tasks: %d \n",getActiveCount());
		System.out.printf(" MyExecutor : Pending tasks: %d \n",getQueue().size());
		
		super.shutdown();
	}


	@Override
	public List<Runnable> shutdownNow() {

		System.out.printf(" MyExecutor :going to immediately shudown .\n");
		System.out.printf(" MyExecutor : Executed tasks: %d \n",getCompletedTaskCount());
		System.out.printf(" MyExecutor : Runing tasks: %d \n",getActiveCount());
		System.out.printf(" MyExecutor : Pending tasks: %d \n",getQueue().size());
		return super.shutdownNow();
	}


	@Override
	protected void beforeExecute(Thread t, Runnable r) {
		System.out.printf(" MyExecutor : A task is beginning :%s : %s \n" ,t.getName(),r.hashCode());
		startTimes.put(String.valueOf(r.hashCode()), new Date());
	}


	@Override
	protected void afterExecute(Runnable r, Throwable t) {
		super.afterExecute(r, t);
		Future<?> result = (Future<?>) r;
		
		try {
			System.out.printf("************************************\n");
			System.out.printf(" MyExecutor ： A task is finishing \n");
			System.out.printf(" MyExecutor ： Result : %s \n" , result.get());
			
			Date start = startTimes.remove(String.valueOf(r.hashCode()));
			Date finish = new Date();
			long diff = finish.getTime() - start.getTime();
			System.out.printf(" MyExecutor : duration : %d \n",diff);
			System.out.println("************************************");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	

		
	
	
}
